package com.jintian.smart.kernel.orm.raw.condition;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.jintian.smart.kernel.core.exception.SmartException;
import lombok.Data;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonTypeName("ArithQuery")
public class ArithCondition extends RawCondition {
    @JsonProperty("field")
    private String field;
    @JsonProperty("value")
    private Object value;
    @JsonProperty("value2")
    private Object value2;
    @JsonProperty("arith")
    private Arith arith;

    public ArithCondition() {
    }

    public ArithCondition(Arith arith, String field) {
        this.field = field;
        this.arith = arith;
    }

    public ArithCondition(Arith arith, String field, Object value) {
        this.field = field;
        this.value = value;
        this.arith = arith;
    }

    public ArithCondition(Arith arith, String field, Object value, Object value2) {
        this.field = field;
        this.value = value;
        this.value2 = value2;
        this.arith = arith;
    }

    @Override
    public String toSql() {
        if (arith == Arith.In || arith == Arith.NotIn) {
            if (!(value instanceof List)) {
                throw new SmartException(String.format("参数%s不是列表类型", value.toString()));
            }
            List<?> values = (List<?>) value;
            StringBuilder sb = new StringBuilder();
            sb.append(field).append(" ").append(arith.op()).append(" (");
            for (int i = 0; i < values.size(); i++) {
                sb.append("?");
                if (i < values.size() - 1) {
                    sb.append(", ");
                }
            }
            sb.append(")");
            return sb.toString();
        } else if (arith == Arith.Between || arith == Arith.NotBetween) {
            return field + " " + arith.op() + " ? AND ?";
        } else if (arith == Arith.IsNull || arith == Arith.IsNotNull) {
            return field + " " + arith.op();
        }

        return field + " " + arith.op() + " ?";
    }

    @Override
    public List<Object> toParamList() {
        if (arith == Arith.In || arith == Arith.NotIn) {
            if (!(value instanceof List)) {
                throw new SmartException(String.format("参数%s不是列表类型", value.toString()));
            }
            return new ArrayList<>((List<?>) value);
        } else if (arith == Arith.Between || arith == Arith.NotBetween) {
            return new ArrayList<>((Arrays.asList(value, value2)));
        } else if (arith == Arith.IsNull || arith == Arith.IsNotNull) {
            return Collections.emptyList();
        }
        return Collections.singletonList(value);
    }
}
